﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Net;
using System.Windows.Browser;

namespace SilverQuery
{
	/// <summary>
	/// Event callback delegate for managed jQuery events.
	/// </summary>
	/// <param name="evt"></param>
	/// <returns></returns>
	public delegate bool EventCallback(HtmlObject sender, Event evt);

	/// <summary>
	/// Callback for non-event callbacks such as with animations.
	/// </summary>
	public delegate void Callback();

	/// <summary>
	/// Central manager for callbacks from JavaScript into SilverQuery.
	/// </summary>
	internal static class CallbackManager
	{
		// Lookup of the handler method delegates.
		private static Dictionary<string, EventCallback> _eventCallbacks = new Dictionary<string, EventCallback>();
		private static Dictionary<string, Callback> _callbacks = new Dictionary<string, Callback>();

		/// <summary>
		/// Trigger the event callback with the specified Id to fire.
		/// </summary>
		internal static bool TriggerEvent(HtmlObject sender, string handlerId)
		{
			var scriptCallbackRegistry = SilverQueryBridge.GetScriptProperty("eventRegistry");
			var nativeEvent = (ScriptObject)scriptCallbackRegistry.GetProperty(handlerId);
			
			EventCallback callback;
			if (_eventCallbacks.TryGetValue(handlerId, out callback))
				return callback(sender, Event.Create(nativeEvent));

			return true;
		}

		/// <summary>
		/// Trigger the callback with the specified Id to fire.
		/// </summary>
		/// <param name="handlerId"></param>
		internal static void Trigger(string callbackId)
		{
			Callback callback;
			if (_callbacks.TryGetValue(callbackId, out callback))
				callback();
		}

		internal static ScriptObject GetScriptEventCallback(EventCallback callback)
		{
			if (callback == null)
				return null; 

			// Create a new unique identifier for this event handler.
			var callbackId = Guid.NewGuid().ToString();
			_eventCallbacks[callbackId] = callback;

			return (ScriptObject)SilverQueryBridge.InvokeScriptFunction("createEventCallback", callbackId);
		}

		internal static ScriptObject GetScriptCallback(Callback callback)
		{
			if (callback == null)
				return null;

			var callbackId = Guid.NewGuid().ToString();
			_callbacks[callbackId] = callback;

			return (ScriptObject)SilverQueryBridge.InvokeScriptFunction("createCallback", callbackId);
		}
	}
}
